package com.mingqijia.gassafety.console.controller.inner;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gap.basic.base.CommonResponse;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.db.entity.Dtu;
import com.mingqijia.gassafety.db.entity.RunningReport;
import com.mingqijia.gassafety.db.entity.RunningReportData;
import com.mingqijia.gassafety.db.entity.vo.HistoryAlarmVo;
import com.mingqijia.gassafety.db.entity.vo.HistoryBrokenVO;
import com.mingqijia.gassafety.db.entity.vo.LatestLogListVO;
import com.mingqijia.gassafety.db.mapper.HistoryAlarmMapper;
import com.mingqijia.gassafety.db.mapper.HistoryBrokenMapper;
import com.mingqijia.gassafety.db.mapper.RunningReportDataMapper;
import com.mingqijia.gassafety.db.mapper.RunningReportMapper;
import com.mingqijia.gassafety.shared.constant.AppealStateEnum;
import com.mingqijia.gassafety.shared.constant.EquipmentType;
import com.mingqijia.gassafety.shared.constant.TemplateTypeEnum;
import com.mingqijia.gassafety.shared.constant.runningReport.ReportAlarmTypeEnum;
import com.mingqijia.gassafety.shared.utils.TimeUtil;
import com.mingqijia.gassafety.shared.utils.commonUtils.DateUtils;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import com.mingqijia.gassafety.webserver.request.LatestLogListRequest;
import com.mingqijia.gassafety.webserver.request.RecordLogRequest;
import com.mingqijia.gassafety.webserver.request.inner.LatestListRequest;
import com.mingqijia.gassafety.webserver.request.inner.LatestSummaryRequest;
import com.mingqijia.gassafety.webserver.response.*;
import com.mingqijia.gassafety.webserver.response.client.ClientAlertRes;
import com.mingqijia.gassafety.webserver.response.client.ConcentrationCurveRes;
import com.mingqijia.gassafety.webserver.response.client.H5LogRes;
import com.mingqijia.gassafety.webserver.service.*;
import com.mingqijia.gassafety.webserver.service.workorder.DtuBindingOrderService;
import com.mingqijia.gassafety.webserver.service.workorder.WorkOrderHistoryService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.util.StringList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 实时状态
 *
 * @author guoliang.lao
 * @since 2022-02-18
 */

@Slf4j
@Api(tags = "实时监测内部")
@RestController(value = "LatestController")
@RequestMapping("/inner/v1/asst/latest/log")
public class LatestController {
    @Autowired
    EquipmentService equipmentService;
    @Autowired
    LatestLogService latestLogService;
    @Autowired
    ConsumerService consumerService;
    @Autowired
    ContactsService contactsService;
    @Autowired
    ConfigureHolder holder;
    @Autowired
    HistoryLogService historyLogService;
    @Autowired
    DtuBindingOrderService dtuBindingOrderService;
    @Autowired
    HistoryBrokenService historyBrokenService;
    @Autowired
    HistoryAlarmService historyAlarmService;
    @Autowired
    HistoryAlarmMapper historyAlarmMapper;
    @Autowired
    HistoryBrokenMapper historyBrokenMapper;
    @Autowired
    RunningReportMapper runningReportMapper;
    @Autowired
    RunningReportDataMapper runningReportDataMapper;
    @Autowired
    WorkOrderHistoryService orderHistoryService;

    @ApiOperation("查询实时状态列表for企业")
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    public CommonResponse<PageUtil<LatestLogListResponse>> listForCompany(@RequestBody LatestLogListRequest request) {
        return CommonResponse.success(latestLogService.getList(request));
    }

    @ApiOperation("查询实时状态列表for师傅")
    @RequestMapping(value = "/servicer/list", method = RequestMethod.POST)
    public CommonResponse<PageUtil<LatestLogListResponse>> listForServicer(@RequestBody LatestListRequest request) {
        return CommonResponse.success(latestLogService.getListByLonAndLat(request));
    }

    @ApiOperation("查询实时状态数量for企业")
    @RequestMapping(value = "summary", method = RequestMethod.POST)
    public CommonResponse<LatestSummaryResponse> summaryForCompany(@RequestBody LatestSummaryRequest request) {
        return CommonResponse.success(latestLogService.getSummary(request));
    }

    @ApiOperation("查询实时状态数量for师傅")
    @RequestMapping(value = "/servicer/summary", method = RequestMethod.POST)
    public CommonResponse<LatestSummaryResponse> summaryForServicer(@RequestBody LatestSummaryRequest request) {
        return CommonResponse.success(latestLogService.getSummaryByLonAndLat(request));
    }

    @ApiOperation("报警浓度曲线")
    @RequestMapping(value = "historyLog", method = RequestMethod.GET)
    public CommonResponse<List<ConcentrationCurveRes>> historyLog(@RequestParam @ApiParam(value = "设备号") String imei,
                                                                  @RequestParam @ApiParam(value = "开始时间") String timeStart,
                                                                  @RequestParam @ApiParam(value = "结束时间") String timeEnd) {
        if (StringUtils.isEmpty(imei)) return CommonResponse.failure("设备号不能为空！");
        if (StringUtils.isEmpty(timeStart)) return CommonResponse.failure("开始时间不能为空！");
        if (StringUtils.isEmpty(timeEnd)) return CommonResponse.failure("结束时间不能为空！");
        return CommonResponse.success(historyLogService.getConcentrationCurve(imei, timeStart, timeEnd));
    }

    @ApiOperation("报警记录")
    @RequestMapping(value = "alertList", method = RequestMethod.GET)
    public CommonResponse<PageUtil<ClientAlertRes>> alertList(@RequestParam @ApiParam(value = "设备号") String imei,
                                                              @RequestParam @ApiParam(value = "页数") Integer page,
                                                              @RequestParam @ApiParam(value = "条数") Integer pageSize) {
        List<ClientAlertRes> resultList = new ArrayList<>();
        //设备基础信息
        LambdaQueryWrapper<Dtu> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(Dtu::getIMEI, imei).eq(Dtu::getIsDeleted, 0);
        Dtu equipment = equipmentService.getOne(queryWrapper);
        if (equipment == null) {
            return CommonResponse.failure("设备不存在");
        }
        if (EquipmentType.GAS_ALARM_CONTROLLER.getCode().equals(equipment.getEquipmentType())) {
            return CommonResponse.success(new PageUtil(page, pageSize, 0, new ArrayList()));
        }
        RecordLogRequest req = new RecordLogRequest();
        req.setImei(imei);
        req.setSpId(equipment.getSpId());
        req.setPage(page);
        req.setPageSize(pageSize);
        req.setTemplateType(TemplateTypeEnum.TEMPLATE_TYPE_1.getCode());
        PageUtil<AlertLogResponse> pageUtil = historyAlarmService.getAlarmList(req);
        for (AlertLogResponse alertLogResponse : pageUtil.getList()) {
            ClientAlertRes res = new ClientAlertRes();
            res.setImei(alertLogResponse.getImei());
            res.setEventTime(alertLogResponse.getLatestTime());
            res.setEquipmentManufacturer("报警");
            res.setEventInfo("");
            resultList.add(res);
        }
        PageUtil pageInfo = new PageUtil(req.getPage(), req.getPageSize(), pageUtil.getTotal(), resultList);
        return CommonResponse.success(pageInfo);
    }

    @ApiOperation("故障记录")
    @RequestMapping(value = "brokenList", method = RequestMethod.GET)
    public CommonResponse<PageUtil<ClientAlertRes>> brokenList(@RequestParam @ApiParam(value = "设备号") String imei,
                                                               @RequestParam @ApiParam(value = "页数") Integer page,
                                                               @RequestParam @ApiParam(value = "条数") Integer pageSize) {
        List<ClientAlertRes> resultList = new ArrayList<>();
        //设备基础信息
        LambdaQueryWrapper<Dtu> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(Dtu::getIMEI, imei).eq(Dtu::getIsDeleted, 0);
        Dtu equipment = equipmentService.getOne(queryWrapper);
        if (equipment == null) {
            return CommonResponse.failure("设备不存在");
        }
        RecordLogRequest req = new RecordLogRequest();
        req.setImei(imei);
        req.setSpId(equipment.getSpId());
        req.setPage(page);
        req.setPageSize(pageSize);
        req.setTemplateType(TemplateTypeEnum.TEMPLATE_TYPE_1.getCode());
        PageUtil<BrokenLogResponse> pageUtil = historyBrokenService.getList(req);
        for (BrokenLogResponse brokenLogResponse : pageUtil.getList()) {
            ClientAlertRes res = new ClientAlertRes();
            res.setImei(brokenLogResponse.getImei());
            res.setEventTime(brokenLogResponse.getLatestTime());
            res.setEquipmentManufacturer("故障");
            res.setEventInfo(brokenLogResponse.getBrokenReason());
            resultList.add(res);
        }
        PageUtil pageInfo = new PageUtil(req.getPage(), req.getPageSize(), pageUtil.getTotal(), resultList);
        return CommonResponse.success(pageInfo);
    }


    @ApiOperation("设备报警故障记录")
    @RequestMapping(value = "alarmBrokenList", method = RequestMethod.GET)
    public CommonResponse<PageUtil<H5LogRes>> alarmBrokenList(@RequestParam @ApiParam(value = "设备号") String imei,
                                                              @RequestParam @ApiParam(value = "页数") Integer page,
                                                              @RequestParam(required = false) @ApiParam(value = "日期") String reportDate,
                                                              @RequestParam @ApiParam(value = "条数") Integer pageSize) {
        List<H5LogRes> resultList = new ArrayList<>();
        log.info("查询报警故障记录入参：{},{}", imei,reportDate);
        //设备基础信息
        LambdaQueryWrapper<Dtu> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(Dtu::getIMEI, imei).eq(Dtu::getIsDeleted, 0);
        Dtu equipment = equipmentService.getOne(queryWrapper);
        if (equipment == null) {
            return CommonResponse.failure("设备不存在");
        }
        LatestLogListVO req = new LatestLogListVO();
        List<String> imeiList = new ArrayList<>();
        imeiList.add(imei);
        req.setImeiList(imeiList);
        req.setReportDate(reportDate);
        List<String> list = new ArrayList<>();
        list.add(equipment.getSpId());
        req.setSpIds(list);

        if (!EquipmentType.GAS_ALARM_CONTROLLER.getCode().equals(equipment.getEquipmentType())){
            List<HistoryAlarmVo> vccRecord = historyAlarmMapper.getVccRecord(req);
            for (HistoryAlarmVo historyAlarmVo : vccRecord) {
                H5LogRes res = new H5LogRes();
                res.setImei(historyAlarmVo.getImei());
                res.setEventTime(historyAlarmVo.getLatestTime());
                res.setEventType(1);
                res.setEventInfo("泄漏报警");
                res.setWarnDuration(historyAlarmVo.getWarnDuration());
                if (historyAlarmVo.getAppealStatus().equals(AppealStateEnum.WAITING_HANDLE.getCode()) ||
                        historyAlarmVo.getAppealStatus().equals(AppealStateEnum.HANDLING.getCode())) {
                    res.setStatus(0);
                } else {
                    res.setStatus(1);
                }
                resultList.add(res);
            }
        }

        List<HistoryBrokenVO> brokenList = historyBrokenMapper.getVccRecord(req);
        for (HistoryBrokenVO historyBrokenVO : brokenList) {
            H5LogRes res = new H5LogRes();
            res.setImei(historyBrokenVO.getImei());
            res.setEventTime(historyBrokenVO.getLatestTime());
            res.setEventType(2);
            res.setEventInfo(historyBrokenVO.getBrokenReason());
            if (historyBrokenVO.getAppealStatus().equals(AppealStateEnum.WAITING_HANDLE.getCode()) ||
                    historyBrokenVO.getAppealStatus().equals(AppealStateEnum.HANDLING.getCode())) {
                res.setStatus(0);
            } else {
                res.setStatus(1);
            }
            resultList.add(res);
        }
        List<H5LogRes> collect = resultList.stream().sorted(Comparator.comparing(H5LogRes::getEventTime).reversed())
                .skip((page - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        PageUtil pageInfo = new PageUtil(page, pageSize, collect.size(), collect);
        log.info("查询报警故障记录结果：{}", pageInfo);
        return CommonResponse.success(pageInfo);
    }

    @ApiOperation("运行报告设备报警故障记录")
    @RequestMapping(value = "reportAlarmBrokenList", method = RequestMethod.GET)
    public CommonResponse<PageUtil<H5LogRes>> reportAlarmBrokenList(@RequestParam @ApiParam(value = "设备号") String imei,
                                                              @RequestParam @ApiParam(value = "页数") Integer page,
                                                              @RequestParam(required = false) @ApiParam(value = "日期") String reportDate,
                                                              @RequestParam @ApiParam(value = "是否预览 0-否 1-是") Integer isForTrial,
                                                              @RequestParam @ApiParam(value = "条数") Integer pageSize) {
        List<H5LogRes> resultList = new ArrayList<>();
        log.info("运行报告设备报警故障记录：{},{}", imei,reportDate);

        //设备基础信息
        LambdaQueryWrapper<Dtu> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(Dtu::getIMEI, imei).eq(Dtu::getIsDeleted, 0);
        Dtu equipment = equipmentService.getOne(queryWrapper);
        if (equipment == null) {
            return CommonResponse.failure("设备不存在");
        }
        String date = StringUtils.isEmpty(reportDate) ? DateUtil.format(DateUtil.offsetMonth(new Date(), -1), "yyyy-MM") : reportDate;
        QueryWrapper<RunningReport> reportQueryWrapper = new QueryWrapper<>();
        reportQueryWrapper.lambda().eq(RunningReport::getIsDeleted,0)
                .eq(RunningReport::getConsumerId,equipment.getConsumerId())
                .eq(RunningReport::getReportDate,date);
        RunningReport report = runningReportMapper.selectOne(reportQueryWrapper);
        log.info("report-report:{}", JSONObject.toJSONString(report));
        if (report == null || (report.getCheckStatus() == 0 && isForTrial == 0)) {
            return CommonResponse.success(new PageUtil(page, pageSize, 0, resultList));
        }

        Page<RunningReportData> pageHelp = PageHelper.startPage(page, pageSize);
        // 报警故障列表
        QueryWrapper<RunningReportData> runningReportDataQueryWrapper = new QueryWrapper<>();
        runningReportDataQueryWrapper.lambda().eq(RunningReportData::getSpId, equipment.getSpId())
                .eq(RunningReportData::getIsDeleted, 0)
                .like(RunningReportData::getImei, imei)
                .eq(RunningReportData::getReportId, report.getId());
        List<RunningReportData> runningReportDataList = runningReportDataMapper.selectList(runningReportDataQueryWrapper);
        if (!CollectionUtils.isEmpty(runningReportDataList)) {
            for (RunningReportData data : runningReportDataList) {
                if (data.getAlarmType() == 0) {
                    if (data.getAppealStatus().equals(AppealStateEnum.WAITING_HANDLE.getCode()) ||
                            data.getAppealStatus().equals(AppealStateEnum.HANDLING.getCode())) {
                    }
                }else if (data.getAlarmType() == 1) {
                    if (data.getAppealStatus().equals(AppealStateEnum.WAITING_HANDLE.getCode()) ||
                            data.getAppealStatus().equals(AppealStateEnum.HANDLING.getCode())) {
                    }
                }
                H5LogRes res = new H5LogRes();
                res.setImei(data.getImei());
                res.setEventTime(data.getAlarmTime());
                res.setEventTimeStr(DateUtils.format(data.getAlarmTime(), "yyyy-MM-dd HH:mm:ss"));
                res.setEventType(data.getAlarmType());
                res.setEventInfo(data.getValveBrokenInfo());
//                res.setEventInfo("泄漏报警");
                if (data.getAlarmType() - ReportAlarmTypeEnum.OFFLINE.getCode() == 0) {
                    // 离线时间
                    if (data.getOfflineExtend() == 1 && res.getEventTime() != null) {
                        res.setEventTimeStr(new StringBuffer("从").append(res.getEventTimeStr()).append("持续离线").toString());
                    }
                    // 离线时长
                    res.setWarnDuration(TimeUtil.secondToStr(data.getOfflineTime()));
                } else {
                    // 报警，故障
                    if (data.getAppealStatus().equals(AppealStateEnum.WAITING_HANDLE.getCode()) ||
                            data.getAppealStatus().equals(AppealStateEnum.HANDLING.getCode())) {
                        res.setStatus(0);
                    } else {
                        res.setStatus(1);
                    }
                }
                resultList.add(res);
            }
        }

        PageUtil<H5LogRes> pageUtil = new PageUtil<>();
        pageUtil.setPage(page);
        pageUtil.setPageSize(pageSize);
        pageUtil.setTotal(pageHelp.getTotal());
        pageUtil.setList(resultList);
        return CommonResponse.success(pageUtil);
    }


    /**
     * 获取历史工单处理详情
     *
     * @param orderNo
     * @return
     */
    @ApiOperation("获取工单处理详情")
    @RequestMapping(value = "/orderHistoryDetail", method = RequestMethod.GET)
    public CommonResponse<AppealLogResponse> orderHistoryDetail(@RequestParam("orderNo") String orderNo) {
        return CommonResponse.success(latestLogService.orderHistoryDetail(orderNo));
    }
}

